/*
 * Copyright (C) 2024 HiHope Open Source Organization.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import createOrGet from '../utils/SingleInstanceHelper';
import { Context } from '@kit.AbilityKit';
import { display, window } from '@kit.ArkUI';
import { Log } from '../utils/Log';

export interface Rect {
  top: number,
  left: number,
  width: number,
  height: number
}

const TAG: string = 'WindowManager'

const DEFAULT_DISPLAY_HEIGHT = 1280;
const DEFAULT_STATUSBAR_HEIGHT = 72;

export class WindowManager {
  displayHeight: number = DEFAULT_DISPLAY_HEIGHT;

  init() {
    this.displayHeight = display.getDefaultDisplaySync().height;
    AppStorage.set('displayHeightWithoutStatusBar', this.displayHeight - DEFAULT_STATUSBAR_HEIGHT);
    window.on('systemBarTintChange', (systemBarTintState: window.SystemBarTintState) => {
      systemBarTintState.regionTint.forEach((tint) => {
        if (tint.type == window.WindowType.TYPE_STATUS_BAR && tint.region) {
          Log.debug(TAG, 'systemBarTintChange ' + JSON.stringify(systemBarTintState));
          AppStorage.set('displayHeightWithoutStatusBar', this.displayHeight - tint.region.height);
        }
      })
    });
  }

  async createWindow(context: Context, name: string, rect: Rect, type: window.WindowType,
    content): Promise<window.Window> {
    Log.info(TAG, `createWindow name: ${name}, rect: ${JSON.stringify(rect)}, url: ${content}`);
    let windowInstance: window.Window
    try {
      windowInstance = await window.createWindow({ ctx: context, name, windowType: type });
      await windowInstance.moveWindowTo(rect.left, rect.top);
      await windowInstance.resize(rect.width, rect.height);
      await windowInstance.setUIContent(content);
      Log.info(TAG, `create window[${name}] success.`);
    } catch (e) {
      Log.error(TAG, `create window[${name}] failed: ${e}, ${JSON.stringify(e)}.`);
    }
    return windowInstance
  }

  async destroyWindow(name: string) {
    Log.info(TAG, `destroyWindow name: ${name}`);
    try {
      let windowInstance = await window.findWindow(name);
      await windowInstance.destroyWindow()
      Log.info(TAG, `destory window[${name}] success.`);
    } catch (e) {
      Log.error(TAG, `destory window[${name}] failed: ${e}, ${JSON.stringify(e)}.`);
    }
  }

  async resizeWindow(name: string, rect: Rect) {
    Log.info(TAG, `resizeWindow name: ${name}`);
    try {
      let windowInstance = await window.findWindow(name);
      await windowInstance.moveWindowTo(rect.left, rect.top)
      await windowInstance.resize(rect.width, rect.height)
      Log.info(TAG, `resize window[${name}] success.`);
    } catch (e) {
      Log.error(TAG, `resize window[${name}] failed: ${e}, ${JSON.stringify(e)}.`);
    }
  }

  async showWindow(name: string, x?: number, y?: number) {
    Log.info(TAG, `showWindow name: ${name}`);
    try {
      let windowInstance = await window.findWindow(name);
      await windowInstance.showWindow();
      await windowInstance.setWindowSystemBarProperties({ statusBarColor: '#00000000', navigationBarColor: '#00000000' });
      if (x != undefined && y != undefined) {
        await windowInstance.moveWindowTo(x, y);
      }
      Log.info(TAG, `show window[${name}] success.`);
    } catch (e) {
      Log.error(TAG, `show window[${name}] failed: ${e}, ${JSON.stringify(e)}.`);
    }
  }

  async hideWindow(name: string) {
    Log.info(TAG, `hideWindow name: ${name}`);
    try {
      let windowInstance = await window.findWindow(name);
      await windowInstance.hide();
      Log.info(TAG, `hide window[${name}] success.`);
    } catch (e) {
      Log.error(TAG, `hide window[${name}] failed: ${e}, ${JSON.stringify(e)}.`);
    }
  }

  isDisplayHorizontal(): boolean {
    let isDisplayHorizontal: boolean;
    let defaultDisplayOrientation = display.getDefaultDisplaySync().orientation;
    Log.info(TAG, `defaultDisplayOrientation = ${defaultDisplayOrientation}`)
    switch (defaultDisplayOrientation) {
      case display.Orientation.LANDSCAPE:
      case display.Orientation.LANDSCAPE_INVERTED:
        isDisplayHorizontal = true
        break;
      case display.Orientation.PORTRAIT:
      case display.Orientation.PORTRAIT_INVERTED:
        isDisplayHorizontal = false
        break;
      default:
        isDisplayHorizontal = false
        break;
    }
    return isDisplayHorizontal;
  }
}

const sWindowManager: WindowManager = createOrGet(WindowManager, 'WindowManager')

export default sWindowManager